import 'package:bot_toast/bot_toast.dart';
import 'package:ca_common_plugin/ca_common_plugin.dart';
import 'package:flutter/material.dart';

// https://x5xmk3djj2.feishu.cn/sheets/U8T0skMCkhUe6WtFSNKcPDOtnpf?sheet=f9bc75

// 弹窗类型
enum CADialogType {
  normal,   // 正常居中弹窗
  top,      // 顶部弹窗
  bottom,   // 底部弹窗
}

// 位置
enum Position {
  left,     // 左
  center,   // 中
  right,    // 右
}

// 按钮布局
enum BtnLayoutType {
  row,      // 横向
  column,   // 纵向
}



class CADialog{
  BuildContext context;                   // 弹窗上下文
  CADialogType dialogType;                // 弹窗类型
  String dialogBackgroundColor;             // 弹窗颜色
  bool isLarge;                           // 是否大字版
  EdgeInsetsGeometry  padding;            // 弹窗内间距
  EdgeInsetsGeometry margin;              // 弹窗外间距
  List<Widget> widgetList;                // 自定义弹窗列表

  bool barrierDismissible;                // 是否点击背景消除
  Color barrierColor;                     // 背景颜色
  Function(BuildContext) dismissCallBack; // 点击背景关闭回调

  bool isShowCloseBtn;                    // 是否显示关闭按钮
  Function(BuildContext) closeCallBack;   // 关闭按钮回调函数

  String netImageUrl;                     // 网图路径
  double imageWidth;                      // 图片大小
  Widget customImage;                     // 自定义图片
  
  String title;                           // 标题
  TextStyle titleTextStyle;               // 标题样式
  Widget customTitleWidget;               // 自定义标题

  String description;                     // 描述
  TextStyle desTextStyle;                 // 描述样式
  bool isScroll;                          // 是否滚动
  double maxScrollHeight;                 // 最大可滚动高度
  Widget customDesWidget;                 // 自定义描述

  String sureText;                        // 确认按钮文案
  TextStyle sureTextStyle;                // 确认文案样式
  Widget customSureBtn;                   // 自定义确认按钮
  Function(BuildContext) sureCallBack;    // 成功按钮回调函数

  String cancelText;                      // 取消按钮文案
  TextStyle cancelTextStyle;              // 取消文案样式
  Widget customCancelBtn;                 // 自定义取消按钮
  Function(BuildContext) cancelCallBack;  // 取消按钮回调

  BtnLayoutType btnLayoutType;            // 按钮布局样式
  Widget customBtns;                      // 自定义按钮

  CADialog(
    this.context,
    {
      this.dialogType = CADialogType.normal,
      this.dialogBackgroundColor = '',
      this.isLarge = false,
      this.margin,
      this.padding,
      this.widgetList,

      this.barrierDismissible = false,
      this.barrierColor = const Color.fromRGBO(0, 0, 0, 0.7),
      this.dismissCallBack,

      this.isShowCloseBtn = false,
      this.closeCallBack,

      this.imageWidth = 80,
      this.netImageUrl = '',
      this.customImage,

      this.title = '',
      this.titleTextStyle = const TextStyle(
        fontSize: 17,
        fontWeight: CAFontWeightRes.SemiBold,
        color: ColorsRes.color_2c2c2c,
      ),
      this.customTitleWidget,

      this.description = '',
      this.desTextStyle = const TextStyle(
        fontSize: 15,
        fontWeight: CAFontWeightRes.Regular,
        color: ColorsRes.color_2c2c2c,
      ),
      this.isScroll = false,
      this.maxScrollHeight = 100,
      this.customDesWidget,

      this.sureText = '',
      this.sureTextStyle = const TextStyle(
        fontSize: 14,
        fontWeight: CAFontWeightRes.SemiBold,
        color: ColorsRes.color_white,
      ),
      this.customSureBtn,
      this.sureCallBack,

      this.cancelText = '',
      this.cancelTextStyle = const TextStyle(
        fontSize: 14,
        fontWeight: CAFontWeightRes.Regular,
        color: ColorsRes.color_38539A,
      ),
      this.customCancelBtn,
      this.cancelCallBack,

      this.btnLayoutType = BtnLayoutType.row,
      this.customBtns,

    }
  ) : assert(
    !CATextUtil.isEmpty(title) || !CATextUtil.isEmpty(description) || widgetList != null || customTitleWidget != null
  );

  // ignore: always_declare_return_types
  Future<void> show(){
    return showGeneralDialog(
      context: context,
      barrierDismissible: barrierDismissible,
      barrierColor: barrierColor,
      barrierLabel: '',
      transitionDuration: const Duration(milliseconds: 300),
      pageBuilder:(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
        return WillPopScope(
          onWillPop: () async => false,
          child: CADialogUtil(
            context: context,
            dialogType: dialogType,
            dialogBackgroundColor: dialogBackgroundColor,
            isLarge: isLarge,
            margin: margin,
            padding: padding,
            widgetList: widgetList,
            isShowCloseBtn: isShowCloseBtn,
            closeCallBack: closeCallBack,
            netImageUrl: netImageUrl,
            imageWidth: imageWidth,
            customImage: customImage,
            title: title,
            titleTextStyle: titleTextStyle, 
            customTitleWidget: customTitleWidget,
            description: description, 
            desTextStyle: desTextStyle, 
            isScroll: isScroll, 
            maxScrollHeight: maxScrollHeight, 
            customDesWidget: customDesWidget, 
            sureText: sureText, 
            sureTextStyle: sureTextStyle, 
            customSureBtn: customSureBtn, 
            sureCallBack: sureCallBack, 
            cancelText: cancelText, 
            cancelTextStyle: cancelTextStyle, 
            customCancelBtn: customCancelBtn, 
            cancelCallBack: cancelCallBack, 
            btnLayoutType: btnLayoutType, 
            customBtns: customBtns,
          )
        );
      },
    );
  }
}

class CADialogUtil extends StatefulWidget{
  final BuildContext context;
  final CADialogType dialogType;
  final EdgeInsetsGeometry margin;
  final EdgeInsetsGeometry padding;
  final BtnLayoutType btnLayoutType;
  final List<Widget> widgetList;
  final double maxScrollHeight;
  final double imageWidth;
  final bool isShowCloseBtn;
  final bool isLarge;
  final bool isScroll;
  final String sureText;
  final String cancelText;
  final String description;
  final String netImageUrl;
  final String title;
  final String dialogBackgroundColor;
  final TextStyle sureTextStyle;
  final TextStyle cancelTextStyle;
  final TextStyle titleTextStyle;
  final TextStyle desTextStyle;
  final Widget customBtns;
  final Widget customCancelBtn;
  final Widget customSureBtn;
  final Widget customDesWidget;
  final Widget customTitleWidget;
  final Widget customImage;

  final Function(BuildContext) cancelCallBack;
  final Function(BuildContext) sureCallBack;
  final Function(BuildContext) closeCallBack;

  CADialogUtil({
    Key key, 
    this.context, 
    this.dialogType = CADialogType.normal,
    this.dialogBackgroundColor = '', 
    this.isLarge = false,
    this.margin,
    this.padding,
    this.widgetList,
    this.isShowCloseBtn = false, 
    this.closeCallBack, 
    this.netImageUrl = '',
    this.imageWidth = 80, 
    this.customImage, 
    this.title = '',
    this.titleTextStyle = const TextStyle(
      fontSize: 17,
      fontWeight: CAFontWeightRes.SemiBold,
      color: ColorsRes.color_2c2c2c,
    ),
    this.customTitleWidget,
    this.description = '', 
    this.desTextStyle = const TextStyle(
      fontSize: 15,
      fontWeight: CAFontWeightRes.Regular,
      color: ColorsRes.color_2c2c2c,
    ),
    this.isScroll = false, 
    this.maxScrollHeight = 100, 
    this.customDesWidget, 
    this.sureText = '', 
    this.sureTextStyle = const TextStyle(
      fontSize: 14,
      fontWeight: CAFontWeightRes.SemiBold,
      color: ColorsRes.color_white,
    ),
    this.customSureBtn, 
    this.sureCallBack, 
    this.cancelText = '', 
    this.cancelTextStyle = const TextStyle(
      fontSize: 14,
      fontWeight: CAFontWeightRes.Regular,
      color: ColorsRes.color_38539A,
    ),
    this.customCancelBtn, 
    this.cancelCallBack, 
    this.btnLayoutType = BtnLayoutType.row,
    this.customBtns,
  }) : assert(
    !CATextUtil.isEmpty(title) || !CATextUtil.isEmpty(description) || widgetList != null || customTitleWidget != null
  ), super(key: key);

  @override
  State<CADialogUtil> createState() => _CADialogUtilState();
}

class _CADialogUtilState extends State<CADialogUtil>{

  // 弹窗宽度  ---  为在不同设备上做统一，宽度写死（安卓默认单位为dp）
  double dialogWidth = CAScreenUtil().setWidth(300);

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    dialogWidth = widget.isLarge ? CAScreenUtil().setWidth(320) : CAScreenUtil().setWidth(300);
    return SafeArea(
      child: Material(
        type: MaterialType.transparency,
        child: Column(
          // 弹窗位置
          mainAxisAlignment: widget.dialogType == CADialogType.top ?
            MainAxisAlignment.start : widget.dialogType == CADialogType.bottom ?
              MainAxisAlignment.end : MainAxisAlignment.center,
          children: [
            Container(
                width: dialogWidth,
              padding: widget.padding ?? EdgeInsets.only(
                bottom: widget.btnLayoutType == BtnLayoutType.row || CATextUtil.isEmpty(widget.cancelText) 
                  ? 24
                  : 10,
              ),
              decoration: BoxDecoration(
                color: CATextUtil.isEmpty(widget.dialogBackgroundColor) 
                  ? Colors.white 
                  : Color(int.tryParse(widget.dialogBackgroundColor)),
                borderRadius: const BorderRadius.all(Radius.circular(8)),
              ),
              child: Stack(
                children: [
                  // 关闭按钮
                  _buildCloseWidget(),
                  Column(
                    mainAxisSize: MainAxisSize.min,
                    children: widget.widgetList ?? [
                      // 图片
                      widget.customImage ?? _buildImage(),
                      // 标题
                      widget.customTitleWidget ?? _buildTitleWidget(),
                      // 描述
                      widget.customDesWidget ?? _buildDescriptionWidget(),
                      // 按钮
                      widget.customBtns ?? _buildButtonWidget(),
                    ],
                  ),
                ],
              )
              
            ),
          ] 
        ),
      )
    );
  }

  // 关闭按钮
  Widget _buildCloseWidget(){
    if (widget.isShowCloseBtn){
      return CASingleGestureDetector(
        onTap: (){
          if(widget.closeCallBack != null){
            widget.closeCallBack(widget.context);
          } else {
            Navigator.pop(context);
          }
        },
        child: Row(
          // 关闭按钮位置
          mainAxisAlignment: MainAxisAlignment.end,
          children: const [
            Padding(
              padding: EdgeInsets.all(4),
              child: CACommonImage(
                'icon_global_close',
                width: 14,
              ),
            ),
          ]
        )
      );
    } else {
      return Container();
    }
  }

  // 图片
  Widget _buildImage(){
    var imageWidth = widget.imageWidth >= dialogWidth ? dialogWidth : widget.imageWidth;
    if(CATextUtil.isEmpty(widget.netImageUrl)){
      return Container();
    }
    return Container(
      width: imageWidth,
      height: widget.imageWidth >= dialogWidth ? 170 : imageWidth,
      margin: EdgeInsets.only(
        top : imageWidth >= dialogWidth ? 0 : 24,
      ),
      decoration: BoxDecoration(
        color: CATextUtil.isEmpty(widget.dialogBackgroundColor) 
          ? Colors.white 
          : Color(int.tryParse(widget.dialogBackgroundColor)),
        borderRadius: imageWidth >= dialogWidth
          ? const BorderRadius.only(
              topLeft: Radius.circular(8),
              topRight: Radius.circular(8),
            )
          : const BorderRadius.all(Radius.circular(8)),
      ),
      child: !CATextUtil.isEmpty(widget.netImageUrl) 
        ? CACachedNetworkImage(
            widget.netImageUrl,
            imageBuilder: (context, imageProvider) => ClipRRect(
              borderRadius: imageWidth >= dialogWidth
                ? const BorderRadius.only(
                    topLeft: Radius.circular(8),
                    topRight: Radius.circular(8),
                  )
                : const BorderRadius.all(Radius.circular(8)),
              child: Container(
                width: imageWidth,
                decoration: BoxDecoration(
                  image: DecorationImage(
                    image: imageProvider,
                    fit: BoxFit.fill,
                  ),
                ),
              ),
            ),
            placeholder: (context, url) => Container(
              width: widget.imageWidth,
              decoration: BoxDecoration(
                color: ColorsRes.bg_gray,
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(widget.imageWidth >= dialogWidth ? 8 : 4),
                  topRight: Radius.circular(widget.imageWidth >= dialogWidth ? 8 : 4),
                  bottomLeft: Radius.circular(widget.imageWidth >= dialogWidth ? 0 : 4),
                  bottomRight: Radius.circular(widget.imageWidth >= dialogWidth ? 0 : 4),
                )
              ),
            ),
            errorWidget: (context, url, error) => Container(
              width: widget.imageWidth,
              decoration: BoxDecoration(
                color: ColorsRes.bg_gray,
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(widget.imageWidth >= dialogWidth ? 8 : 4),
                  topRight: Radius.circular(widget.imageWidth >= dialogWidth ? 8 : 4),
                  bottomLeft: Radius.circular(widget.imageWidth >= dialogWidth ? 0 : 4),
                  bottomRight: Radius.circular(widget.imageWidth >= dialogWidth ? 0 : 4),
                )
              ),
            ),
          )
        : Container()
    );
  }

  // 标题
  Widget _buildTitleWidget(){
    if(CATextUtil.isEmpty(widget.title)){
      return Container();
    }
    return Container(
      margin: const EdgeInsets.only(top: 24),
      alignment: Alignment.center,
      child: Text(
        widget.title,
        maxLines: 1,
        textAlign: TextAlign.center,
        style: widget.isLarge ? const TextStyle(
          fontSize: 24,
          fontWeight: CAFontWeightRes.SemiBold,
          color: ColorsRes.color_2c2c2c,
        ) : widget.titleTextStyle ,
        overflow: TextOverflow.ellipsis,
      ),
    );
  }

  // 描述
  Widget _buildDescriptionWidget(){
    if(CATextUtil.isEmpty(widget.description)){
      return Container();
    }
    // 可滚动
    if(widget.isScroll){
      return Container(
        height: widget.maxScrollHeight,
        margin: EdgeInsets.only(top: CATextUtil.isEmpty(widget.title) ? 24 : 12),
        padding: const EdgeInsets.symmetric(horizontal: 20),
        child: SingleChildScrollView(
          child: Text(
            widget.description ?? "",
            textAlign: TextAlign.center,
            style: widget.isLarge ? const TextStyle(
              fontSize: 20,
              fontWeight: CAFontWeightRes.Regular,
              color: ColorsRes.color_2c2c2c,
            ) : widget.desTextStyle,
          ),
        ),
      );
    } else {
      // 不可滚动
      return Container(
        margin: EdgeInsets.only(top: CATextUtil.isEmpty(widget.title) ? 24 : 12),
        padding: const EdgeInsets.symmetric(horizontal: 20),
        child: Text(
          widget.description,
          textAlign: TextAlign.center,
          style: widget.isLarge ? const TextStyle(
            fontSize: 20,
            fontWeight: CAFontWeightRes.Regular,
            color: ColorsRes.color_2c2c2c,
          ) : widget.desTextStyle,
        ),
      );
    }
  }

  // 按钮列表
  Widget _buildButtonWidget(){
    switch (widget.btnLayoutType) {
      case BtnLayoutType.column:
        return Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            _buildSureButton(),
            _buildCancelButton(),
          ],
        );
        break;
      case BtnLayoutType.row:
      default:
        return Container(
          margin: const EdgeInsets.only(top: 24),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _buildCancelButton(),
              _buildSureButton(),
            ],
          ),
        );
        break;
    }
  }

  // 取消按钮
  Widget _buildCancelButton(){
    if(CATextUtil.isEmpty(widget.cancelText)){
      return Container();
    }
    return widget.customCancelBtn ?? GestureDetector(
      onTap: (){
        if (widget.cancelCallBack != null) {
          widget.cancelCallBack(widget.context);
        } else {
          Navigator.pop(context);
        }
      },
      child: Container(
        height: widget.isLarge ? 48 : 40,
        width: widget.isLarge ? 120 : 116,
        margin: EdgeInsets.only(
          right: widget.btnLayoutType == BtnLayoutType.column 
            ? 0 
            : widget.isLarge
              ? 12 : 20
        ),
        decoration: BoxDecoration(
          border: widget.btnLayoutType == BtnLayoutType.column 
          ? const Border()
          : Border.all(
              width: 1,
              color: ColorsRes.color_38539A
            ),
          color: ColorsRes.color_white,
          borderRadius: BorderRadius.all(Radius.circular(widget.isLarge ? 24 : 20))
        ),
        alignment: Alignment.center,
        child: Text(
          widget.cancelText,
          style: widget.isLarge ? const TextStyle(
            fontSize: 18,
            fontWeight: CAFontWeightRes.Regular,
            color: ColorsRes.color_38539A,
          ) : widget.cancelTextStyle,
        ),
      ),
    );
  }

  // 确认按钮
  Widget _buildSureButton(){
    if(CATextUtil.isEmpty(widget.sureText)){
      return Container();
    }
    return widget.customSureBtn ?? GestureDetector(
      onTap: (){
        if (widget.sureCallBack != null) {
          widget.sureCallBack(widget.context);
        } else {
          Navigator.pop(context);
        }
      },
      child: Container(
        height: widget.isLarge ? 48 : 40,
        width: widget.btnLayoutType == BtnLayoutType.column 
          ? widget.isLarge ? 220 : 212 
          : widget.isLarge ? 120 : 116,
        margin: EdgeInsets.only(top: widget.btnLayoutType == BtnLayoutType.column 
          ? widget.isLarge 
            ? 25 : 22 
          : 0
        ),
        decoration: BoxDecoration(
          color: ColorsRes.color_38539A,
          borderRadius: BorderRadius.all(Radius.circular(widget.isLarge ? 24 : 20))
        ),
        alignment: Alignment.center,
        child: Text(
          widget.sureText,
          style: widget.isLarge ? const TextStyle(
            fontSize: 18,
            fontWeight: CAFontWeightRes.SemiBold,
            color: ColorsRes.color_white,
          ) : widget.sureTextStyle,
        ),
      ),
    );
  }
}

// Toast弹窗
class CADialogToast {
  // 工厂模式, 为了在外面获取开发环境
  factory CADialogToast() => _getInstance();
  static CADialogToast get instance => _getInstance();
  static CADialogToast _instance;
  CADialogToast._internal() {
    // 初始化
  }
  static CADialogToast _getInstance() {
    _instance ?? CADialogToast._internal();
    return _instance;
  }

  ///显示文本
  static void toast(
    String text,                                                  // 文本
    {
      double borderRadius = 8,                                    // Toast圆角
      Color bgColor = const Color.fromRGBO(0, 0, 0, 0.7),         // Toast容器颜色
      TextStyle textStyle = const TextStyle(                      // 文本样式
        fontSize: 16,
        color: Colors.white,
      ),
      EdgeInsetsGeometry margin = const EdgeInsets.symmetric(     // Toast外间距
        horizontal: 20
      ),
      EdgeInsetsGeometry padding = const EdgeInsets.all(12),      // Toast内间距
      int milliseconds = 2000,                                    // Toast时长
      bool isAllowClick = false,                                  // 是否可点击
    }
  ) {
    BotToast.closeAllLoading();
    BotToast.showCustomLoading(
      backgroundColor: Colors.transparent,
      allowClick: isAllowClick,
      toastBuilder: (_) {
        if(CATextUtil.isEmpty(text)){
          return Container();
        }
        return Container(
          margin: margin,
          alignment: Alignment.center,
          child: Card(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(borderRadius)),
            color: bgColor,
            child: Container(
              padding: padding,
              child: Text(
                text,
                textAlign: TextAlign.center, 
                style: textStyle,
              ),
            ),
          )
        );
      },
      duration: Duration(milliseconds: milliseconds),
    );
  }
}